
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import app.Com;
import app.Parameters;



public class SportsLeaderBoardSerial implements Runnable {
    private Com com;
    Thread runner;
    String endMark = "*end*";
	int endMarkLen = endMark.length();
	String startMark = "*start*";
	int startMarkLen = startMark.length();
	SportsLeaderBoardView view;
	
    void start(String port, SportsLeaderBoardView view) throws Exception {
		Parameters param = new Parameters();
	    param.setPort(port);
	    param.setBaudRate("9600");
	    com = new Com(param);
	    this.view = view;
	    
    	runner = new Thread(this, "SportsLeaderBoardSerialThread");
    	runner.start();
    	System.out.println("Serial server started, listening on port " + port + " baudrate 9600");
    }
    
    public void run() {
    	try {
			rec();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	void close() throws Exception {
	    com.close();
	}
    void rec() throws Exception {
    	StringBuffer buf = new StringBuffer(128);
    	int i;
    	for (;;) {
    		i = com.receiveSingleDataInt();
    		if (i != 0) {
//    			System.out.println("Received:" + (char)i);
        		buf.append((char)i);
        		if (isCompletePacket(buf)) {
        			view.setView(parsePacket(buf));
        			buf.setLength(0);
        		}
    		}
    		else {
				Thread.sleep(100);
    		}
    	}  
    }
    
    private List<SportsLeaderBoardViewData> parsePacket(StringBuffer buf) {
    	List<SportsLeaderBoardViewData> result = new ArrayList<SportsLeaderBoardViewData>();
    	Scanner scanner = new Scanner(buf.toString());
    	try {
    		while ( scanner.hasNextLine() ){
    			SportsLeaderBoardViewData d = processLine( scanner.nextLine() );
    			if (d != null) {
    				result.add(d);
    			}
    		}
    	}
    	finally {
    		scanner.close();
    	}
    	return result;
    }
    
    protected SportsLeaderBoardViewData processLine(String aLine){
    	if (aLine.startsWith("*start*") || aLine.startsWith("*end*")) {
    		return null;
    	}
    	System.out.println("Received on serial:" + aLine);
        Scanner scanner = new Scanner(aLine);
        //scanner.useDelimiter(" ");
        SportsLeaderBoardViewData d = new SportsLeaderBoardViewData(); 
        if ( scanner.hasNext("\\d+") ) {
        	d.setPlace(scanner.next());
        }
        if ( scanner.hasNext("\\d+") ) {
        	d.setTrack(scanner.next());
        }
        if ( scanner.hasNext("\\d+") ) {
        	d.setNumber(scanner.next());
        }
        if ( scanner.hasNext("[0-9\\.\\:]+") ) {
        	d.setTime(scanner.next());
        }
        else {
        	System.out.println("Empty or invalid line. Unable to process.");
        	return null;
        }
        System.out.println(d.toString());
        scanner.close();
        return d;
      }
    
    boolean isCompletePacket(StringBuffer buf) {
    	boolean result = false;
    	int bufLen = buf.length();
    	
    	if ((bufLen > endMarkLen) && 
    			(buf.substring(bufLen - endMarkLen).equalsIgnoreCase(endMark))) {
    		result = true;
    	}
    	return result;
    }
}